package com.nuoniu.sibanyun.service.crm.call.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.crm.CrmGoods;
import com.nuoniu.sibanyun.entity.crm.CrmGoodsOrder;
import com.nuoniu.sibanyun.entity.crm.bo.GoodsOrderDetailBo;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallMinutes;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallMinutesDetail;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallMinutesRecord;
import com.nuoniu.sibanyun.entity.crm.call.vo.CrmCallMinutesSimpleVo;
import com.nuoniu.sibanyun.mapper.crm.call.CrmCallMinutesMapper;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsOrderService;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallMinutesDetailService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallMinutesRecordService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallMinutesService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 客户管理-呼叫分钟数 服务实现类
 * </p>
 *
 * @author 白强
 * @since 2022-05-25
 */
@Service
@Log4j2
public class CrmCallMinutesServiceImpl extends ServiceImpl<CrmCallMinutesMapper, CrmCallMinutes> implements ICrmCallMinutesService {

    @Autowired
    private ICrmCallMinutesRecordService crmCallMinutesRecordService;
    @Autowired
    private ICrmGoodsService crmGoodsService;
    @Autowired
    @Lazy
    private ICrmGoodsOrderService goodsOrderService;
    @Autowired
    private ICrmCallMinutesDetailService callMinutesDetailService;
    /**
     * 校验是否初始化
     * @param companyId
     */
    @Override
    public CrmCallMinutes checkByCompanyId(Integer companyId) {
        CrmCallMinutes callMinutes = this.getByCompany(companyId,false);
        if(null == callMinutes){
            LocalDateTime now = LocalDateTime.now();
            //月初
            LocalDateTime startMonth = LocalDateTime.of(now.minusMonths(0L).with(TemporalAdjusters.firstDayOfMonth()).toLocalDate(), LocalTime.MIN);
            //月末
            LocalDateTime endMonth = LocalDateTime.of(now.minusMonths(0L).with(TemporalAdjusters.lastDayOfMonth()).toLocalDate(), LocalTime.MAX);
            int year = now.getYear();
            int month = now.getMonthValue();
            callMinutes = new CrmCallMinutes();
            callMinutes.setCompanyId(companyId);
            callMinutes.setYear(year);
            callMinutes.setMonth(month);
            callMinutes.setStartTime(startMonth);
            callMinutes.setEndTime(endMonth);
            callMinutes.setBaseMinutesTotal(0);
            callMinutes.setBaseMinutesRemain(0);
            callMinutes.setBaseMinutesUsed(0);
            callMinutes.setGeneralMinutesTotal(0);
            callMinutes.setGeneralMinutesRemain(0);
            callMinutes.setGeneralMinutesUsed(0);
            callMinutes.setGeneralMinutesUsedMonth(0);
            callMinutes.setStatus(1);
            this.save(callMinutes);

        }
        return callMinutes;
    }
    /**
     * 查询 当前租户 分钟数情况
     * @return
     */
    @Override
    public CrmCallMinutes getByCompany(Integer companyId,Boolean isListDetail) {
        if(null == companyId){
            UserInfo userInfo = UserThreadLocal.get();
            companyId = userInfo.getCompanyId();
        }
        QueryWrapper<CrmCallMinutes> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",companyId);
        queryWrapper.last("LIMIT 1");
        CrmCallMinutes callMinutes = getOne(queryWrapper, false);
        if(null != callMinutes && null != isListDetail && isListDetail){
            List<CrmCallMinutesDetail> crmCallMinutesDetails = callMinutesDetailService.listByCrmCallMinutesId(callMinutes.getId().intValue());
            callMinutes.setCrmCallMinutesDetailList(crmCallMinutesDetails);
        }
        return callMinutes;
    }
    /**
     * 根据商品订单 更新 分钟数
     * @param crmGoodsOrder
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void changeFromGoodsOrder(CrmGoodsOrder crmGoodsOrder) {
        CrmCallMinutes callMinutes = this.getByCompany(crmGoodsOrder.getCompanyId(),false);
        if(null == callMinutes) {
            throw new NuoNiuException(6001,"外呼功能还未开通");
        }
        String goodsDetail = crmGoodsOrder.getGoodsDetail();
        GoodsOrderDetailBo goodsOrderDetailBo = null;
        if(StringUtils.isNotBlank(goodsDetail)){
            goodsOrderDetailBo = JSON.parseObject(goodsDetail, GoodsOrderDetailBo.class);
        }
        if(null == goodsOrderDetailBo) {
            throw new NuoNiuException("参数错误");
        }
        String goodsType = goodsOrderDetailBo.getGoodsType();
        if(!"telCharges".equals(goodsType)) {
            throw new NuoNiuException("参数错误");
        }
        Boolean isSetting = goodsOrderDetailBo.getIsSetting();
        Integer baseMinutes = goodsOrderDetailBo.getBaseMinutes();
        BigDecimal salePrice = crmGoodsOrder.getSalePrice();
        if(null == callMinutes.getTotalAmount()) {
            callMinutes.setTotalAmount(BigDecimal.ZERO);
        }
        callMinutes.setTotalAmount(callMinutes.getTotalAmount().add(salePrice));
        if( isSetting){
            //套餐 分钟数
            if(null == callMinutes.getBaseAmount()) {
                callMinutes.setBaseAmount(BigDecimal.ZERO);
            }
            callMinutes.setBaseAmount(callMinutes.getBaseAmount().add(salePrice));
            callMinutes.setBaseMinutesRemain((null == callMinutes.getBaseMinutesRemain() ? 0 : callMinutes.getBaseMinutesRemain()) + baseMinutes);
            callMinutes.setBaseMinutesTotal((null == callMinutes.getBaseMinutesTotal() ? 0 : callMinutes.getBaseMinutesTotal()) + baseMinutes);
        }else{
            if(null == callMinutes.getGeneralAmount()) {
                callMinutes.setGeneralAmount(BigDecimal.ZERO);
            }
            callMinutes.setGeneralAmount(callMinutes.getGeneralAmount().add(salePrice));
            callMinutes.setGeneralMinutesRemain((null == callMinutes.getGeneralMinutesRemain() ? 0 : callMinutes.getGeneralMinutesRemain()) + baseMinutes);
            callMinutes.setGeneralMinutesTotal((null == callMinutes.getGeneralMinutesTotal() ? 0 : callMinutes.getGeneralMinutesTotal()) + baseMinutes);
        }
        this.updateById(callMinutes);
        /** 根据商品订单处理业务 */
        callMinutesDetailService.saveFromCrmGoodsOrder(callMinutes,crmGoodsOrder);

    }
    /**
     * 记录话费使用情况（月初执行）
     */
    @Override
    public void recordCrmCallMinutes() {
        log.info("记录话费使用情况（月初执行）_开始");
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime lastNowDate = now.minusMonths(1L).with(TemporalAdjusters.lastDayOfMonth());
        /** 1.查询所有的租户的分钟数情况 */
        int year = lastNowDate.getYear();
        int month = lastNowDate.getMonthValue();
        log.info("记录话费使用情况（月初执行）_lastNowDate:{},{},{}",lastNowDate,year,month);
        Page<CrmCallMinutes> page = new Page<>();
        page.setSize(-1);
        QueryWrapper<CrmCallMinutes>  queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year",year);
        queryWrapper.eq("month",month);
        page(page, queryWrapper);
        List<CrmCallMinutes> crmCallMinutes = page.getRecords();
        this.batchAddRecordCrmCallMinutes(crmCallMinutes);
        while (page.getPages() > page.getCurrent()){
            page.setCurrent(page.getCurrent() + 1);
            page(page, queryWrapper);
            crmCallMinutes = page.getRecords();
            this.batchAddRecordCrmCallMinutes(crmCallMinutes);
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchAddRecordCrmCallMinutes(List<CrmCallMinutes> crmCallMinutes) {
        log.info("分批次 执行自动存档使用情况：数量{}",crmCallMinutes.size());
        LocalDateTime now = LocalDateTime.now();
        int nowYear = now.getYear();
        int nowMonth = now.getMonthValue();
        //月初
        LocalDateTime startMonth = LocalDateTime.of(now.minusMonths(0L).with(TemporalAdjusters.firstDayOfMonth()).toLocalDate(), LocalTime.MIN);
        //月末
        LocalDateTime endMonth = LocalDateTime.of(now.minusMonths(0L).with(TemporalAdjusters.lastDayOfMonth()).toLocalDate(), LocalTime.MAX);
        log.debug("话费管理 月初：{},月末：{}",startMonth,endMonth);
        if(null == crmCallMinutes || crmCallMinutes.size() == 0) {
            return;
        }
        List<CrmCallMinutesRecord> callMinutesRecords = new ArrayList<>();
        int size = crmCallMinutes.size();
        for (int i = 0; i < size; i++) {
            CrmCallMinutes callMinutes = crmCallMinutes.get(i);
            CrmCallMinutesRecord crmCallMinutesRecord = new CrmCallMinutesRecord();
            //赋值
            BeanUtils.copyProperties(callMinutes,crmCallMinutesRecord);
            crmCallMinutesRecord.setId(null);
            crmCallMinutesRecord.setTotalMinutes(crmCallMinutesRecord.getBaseMinutesUsed() + crmCallMinutesRecord.getGeneralMinutesUsedMonth());
            callMinutesRecords.add(crmCallMinutesRecord);
            /** 初始化 当月分钟数*/
            callMinutes.setYear(nowYear);
            callMinutes.setMonth(nowMonth);
            callMinutes.setStartTime(startMonth);
            callMinutes.setEndTime(endMonth);
            callMinutes.setTotalAmount(BigDecimal.ZERO);
            callMinutes.setBaseAmount(BigDecimal.ZERO);
            callMinutes.setGeneralAmount(BigDecimal.ZERO);
            callMinutes.setBaseMinutesUsed(0);
            callMinutes.setBaseMinutesRemain(0);
            callMinutes.setBaseMinutesTotal(0);
            callMinutes.setGeneralMinutesUsedMonth(0);
        }
        this.updateBatchById(crmCallMinutes);
        crmCallMinutesRecordService.saveBatch(callMinutesRecords);
    }

    @Override
    public void closeCallFunction(Integer companyId) {
        CrmCallMinutes callMinutes = this.getByCompany(companyId,false);
        UpdateWrapper<CrmCallMinutes> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",callMinutes.getId());
        updateWrapper.set("status",0);
        update(updateWrapper);
    }

    @Override
    public void openCallFunction(Integer companyId) {
        CrmCallMinutes callMinutes = this.getByCompany(companyId,false);
        UpdateWrapper<CrmCallMinutes> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",callMinutes.getId());
        updateWrapper.set("status",1);
        update(updateWrapper);
    }

    @Override
    public void autoRenewalGoodsSetting() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime lastNowDate = now.minusMonths(1L).with(TemporalAdjusters.lastDayOfMonth());
        /** 1.查询所有的租户的分钟数情况 */
        int year = lastNowDate.getYear();
        int month = lastNowDate.getMonthValue();
        /** 查询自动续费的租户 */
        log.info("自动续费套餐任务开始");
        Page<CrmCallMinutesSimpleVo> page = new Page<>();
        page.setSize(-1);
        baseMapper.pageAutoRenewalData(page,year,month);
        List<CrmCallMinutesSimpleVo> records = page.getRecords();
        this.batchRenewalGoodsSetting(records);
        while (page.getPages() > page.getCurrent()){
            page.setCurrent(page.getCurrent() + 1);
            baseMapper.pageAutoRenewalData(page,year,month);
            records = page.getRecords();
            this.batchRenewalGoodsSetting(records);
        }
    }

    @Override
    public void batchRenewalGoodsSetting(List<CrmCallMinutesSimpleVo> callMinutesSimpleVos) {
        log.info("分批次 执行自动续费任务：数量{}",callMinutesSimpleVos.size());
        int size = callMinutesSimpleVos.size();
        CrmGoodsOrder order;
        for (int i = 0; i < size; i++) {
            CrmCallMinutesSimpleVo crmCallMinutesSimpleVo = callMinutesSimpleVos.get(i);
            log.info("自动续费——租户：{}，套餐商品名称：{}，{}",crmCallMinutesSimpleVo.getCompanyName(),crmCallMinutesSimpleVo.getCrmGoodsName(),crmCallMinutesSimpleVo.getCrmGoodsId());
            order = new CrmGoodsOrder();
            order.setCompanyId(crmCallMinutesSimpleVo.getCompanyId());
            order.setCompanyName(crmCallMinutesSimpleVo.getCompanyName());
            order.setOrderType(3);//订单类型1购买 2升级 3.续费
            order.setPayType(3);
            order.setOrderBusinessType("Goods");
            order.setGoodsId(crmCallMinutesSimpleVo.getCrmGoodsId());
            order.setGoodsName(crmCallMinutesSimpleVo.getCrmGoodsName());
            goodsOrderService.saveOrder(order);
        }

    }

    @Override
    public String isCallEnable() {
        CrmCallMinutes callMinutes = this.getByCompany(null, false);
        if(null == callMinutes) {
            return  "NoInit";  //没有开通功能
        }
        if(!callMinutes.getStatus().equals(1)) {
            return  "Disable"; //功能被停用
        }
        Integer baseMinutesRemain = callMinutes.getBaseMinutesRemain();
        Integer generalMinutesRemain = callMinutes.getGeneralMinutesRemain();
        if((baseMinutesRemain + generalMinutesRemain ) < 1) {
            return "NoMinutes"; //分钟数不足
        }
        return "Enable";
    }

}
